﻿using System;
using MvvmFx.Common.ViewModels;
using MvvmFx.Common.ViewModels.Commands;

namespace MvvmFx.Samples.HowTos.PropertyHandlers.ViewModels
{
    public class PropertyHandlersViewModel : ViewModelBase
    {
        private NumberCollection _numbers;
        private NumberChangeLogViewModel _numberChangeLog;
        private NumberViewModel _selectedNumber;

        public PropertyHandlersViewModel()
        {
            GenerateNumbers(0, 50);

            _newNumbers = new ActionCommand(param => GenerateNumbers());
        }

        private readonly ActionCommand _newNumbers;

        /// <summary>
        /// Gets the value of the <see cref=”NewNumbers”/> property.
        /// </summary>
        public ActionCommand NewNumbers
        {
            get { return _newNumbers; }
        }

        private void GenerateNumbers()
        {
            var rand = new Random(DateTime.Now.Millisecond);
            int from = rand.Next(1000);
            GenerateNumbers(from, from + 50);
        }

        private void GenerateNumbers(int from, int to)
        {
            if (_numbers != null)
                _numbers.Clear();

            var newNumbers = new NumberCollection();

            for (int i = from; i < to; i++)
            {
                newNumbers.Add(new NumberViewModel { Value = i });
            }

            //newNumbers.AddItemHandler("IsEven", (sender, e) => OnPropertyChanged("NumberOfEvens"));
            //newNumbers.AddItemHandler("IsNegative", (sender, e) => OnPropertyChanged("NumberOfNegatives"));

            // becomes:
            //
            newNumbers.NewCollectionObserver()
                .AddHandler("IsEven", n => OnPropertyChanged("NumberOfEvens"))
                .AddHandler("IsNegative", n => OnPropertyChanged("NumberOfNegatives"));
            

            Numbers = newNumbers;
        }

        /// <summary>
        /// Gets or sets the value of the <see cref=”Numbers”/> property.
        /// </summary>
        public NumberCollection Numbers
        {
            get { return _numbers; }
            set
            {
                if (_numbers != value)
                {
                    _numbers = value;
                    OnPropertyChanged("Numbers");
                }
            }
        }

        /// <summary>
        /// Gets or sets the value of the <see cref=”SelectedNumber”/> property.
        /// </summary>
        public NumberViewModel SelectedNumber
        {
            get { return _selectedNumber; }
            set
            {
                if (_selectedNumber != value)
                {
                    _selectedNumber = value;
                    OnPropertyChanged("SelectedNumber");

                    if (_selectedNumber != null)
                    {
                        NumberChangeLog = new NumberChangeLogViewModel(_selectedNumber);
                    }
                }
            }
        }
        /// <summary>
        /// Gets or sets the value of the <see cref=”NumberChangeLog”/> property.
        /// </summary>
        public NumberChangeLogViewModel NumberChangeLog
        {
            get { return _numberChangeLog; }
            set
            {
                if (_numberChangeLog != value)
                {
                    _numberChangeLog = value;
                    OnPropertyChanged("NumberChangeLog");
                }
            }
        }

        /// <summary>
        /// Gets the value of the <see cref=”NumberOfEvens”/> property.
        /// </summary>
        public int NumberOfEvens
        {
            get
            {
                int count = 0;
                foreach (var numberVM in _numbers)
                {
                    if (numberVM.IsEven)
                        count++;
                }
                return count;
            }
        }

        /// <summary>
        /// Gets the value of the <see cref=”NumberOfNegatives”/> property.
        /// </summary>
        public int NumberOfNegatives
        {
            get
            {
                int count = 0;
                foreach (var numberVM in _numbers)
                {
                    if (numberVM.IsNegative)
                        count++;
                }
                return count;
            }
        }
    }
}